package com.example.myDesignPatterns.创建者模式.单例模式.依然存在的问题;

import cn.hutool.core.util.ReflectUtil;

import java.io.*;

/**
 * 破坏单例模式
 * 使用序列化 反射
 * 可以使单例类Singleton 创建多个对象 （枚举方式无法被序列化和反射创建多个对象）
 */
public class Singleton implements java.io.Serializable{
    private Singleton(){}

    public static class SingletonHolder{
        private static final Singleton instance = new Singleton();
    }
    public static Singleton getInstance(){
        return SingletonHolder.instance;
    }
}
class SerializableDestructionDemo{
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        // 序列化与反序列化前正常获取单例
        Singleton singleton1 = Singleton.getInstance();
        System.out.println("Before Serialization & Deserialization, instance: " + singleton1);

        // 序列化单例对象到文件
        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("singleton.ser"))) {
            oos.writeObject(singleton1);
        }

        // 从文件反序列化得到新的对象
        Singleton singleton2 = null;
        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("singleton.ser"))) {
            singleton2 = (Singleton) ois.readObject();
        }

        System.out.println("After Serialization & Deserialization, instance: " + singleton2);

        // 检查是否破坏了单例（在未采用readResolve方法的情况下，这两个实例本应相同但可能不同）
        System.out.println("Are instances the same? " + (singleton1 == singleton2));
    }
}

class ReflectionDestructionDemo{
    public static void main(String[] args) {
        // 获取单例对象
        Singleton singleton1 = Singleton.getInstance();
        System.out.println("Before Reflection, instance: " + singleton1);

        // 使用反射获取单例类中的私有构造方法
        Singleton singleton2 = ReflectUtil.newInstance(Singleton.class);
        System.out.println("After Reflection, instance: " + singleton2);

        // 检查是否破坏了单例（在未采用readResolve方法的情况下，这两个实例本应相同但可能不同）
        System.out.println("Are instances the same? " + (singleton1 == singleton2));
   }
}

/**
 * SingletonPerfect 实现了单例模式，并通过静态内部类方式保证了线程安全和懒加载。
 * 同时，通过重写 readResolve 方法防止了序列化和反序列化破坏单例。
 */
class SingletonPerfect1 implements Serializable {
    private static final long serialVersionUID = -76597547766198971L; // 序列化版本号

    // 私有构造方法，确保外部不能直接实例化
    private SingletonPerfect1() {
        // 构造函数保持为空，实例化工作由 SingletonHolder 完成
    }

    // 静态内部类，用于延迟初始化单例实例
    private static class SingletonHolder {
        private static final SingletonPerfect1 INSTANCE = new SingletonPerfect1();
    }

    // 获取单例实例的公共方法
    public static SingletonPerfect1 getInstance() {
        return SingletonHolder.INSTANCE;
    }

    // 保护单例不被序列化和反序列化破坏
    private Object readResolve() {
        // 反序列化时返回 SingletonHolder 中的单例实例
        return SingletonHolder.INSTANCE;
    }
}